/* 
    @file temp_sensor.c
    @brief 
        
    @author ZhanZhao
    @version 1.0.0
    @date 2025/08/13
*/
#include "temp_sensor.h"
#include "hal-regs.h"
#include "types.h"
#include "adc.h"
#include "ui_event.h"
#include "vin_det.h"

temp_rang_t temp_range;

code uint16_t temp_thr_table[TEMP_RANGE_NUM - 2] = {
    TEMP_VAL_0,
    TEMP_VAL_10,
    TEMP_VAL_45,
    TEMP_VAL_56,
};

code uint16_t temp_hyst_table[TEMP_RANGE_NUM - 2] = {
    TEMP_VAL_1,
    TEMP_VAL_13,
    TEMP_VAL_44,
    TEMP_VAL_55,
};

void temp_sensor_init(void)
{    
    NTCCON |= 0x03;   /* P14 AN6 100uA */
    MFP3 |= 0x03;
}

void temp_sensor_handle(void)
{
    uint16_t sensor_temp;
    int8_t range_diff;
    temp_rang_t temp_range_new;
    static temp_rang_t temp_range_prev;
    static uint8_t temp_confirm_cnt;
    
    sensor_temp = TEMP_SENSOR_GET_TEMP();

    for (temp_range_new = 1; temp_range_new < TEMP_RANGE_NUM - 1; temp_range_new++) {
        if (sensor_temp > temp_thr_table[temp_range_new - 1]) {
            break;
        }
    }

    range_diff = temp_range_new - temp_range;

    if (range_diff == 1) {
        if (temp_range < TEMP_RANGE_NORMAL && sensor_temp > temp_hyst_table[temp_range - 1]) {
            temp_range_new = temp_range;
        }
    } else if (range_diff == -1) {
        if (temp_range > TEMP_RANGE_NORMAL && sensor_temp < temp_hyst_table[temp_range - 2]) {
            temp_range_new = temp_range;
        }
    }

    if (temp_range_new != temp_range_prev) {
        temp_confirm_cnt = 0;
        temp_range_prev = temp_range_new;
    } else if (temp_confirm_cnt < 255) {
        temp_confirm_cnt++;
    }

    if (temp_confirm_cnt == 7) {
        temp_range = temp_range_prev;

        if (temp_is_abnormal() && vin_is_ok()) {
            ui_event |= 1 << UI_EVENT_NTC_ABN;
        }
    }
}

temp_rang_t temp_sensor_get_range(void)
{
    return temp_range;
}

uint8_t temp_is_abnormal(void)
{
    if ((temp_sensor_get_range() < TEMP_RANGE_HIGH_CRITICAL) && (temp_sensor_get_range() > TEMP_RANGE_LOW_CRITICAL)) {
        return 0;
    }

    return 1;
}